package com.xq.utils;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class XmlUtils {


    /**
     * 解析XML转换为Object
     * @param strXML xml字符串
     * @param elementName 解析根标签名
     * @param className 类名全路径（包名+类名）
     * @return
     */
    public static List<Object> parseObject(String strXML, String elementName, String className){
        List<Object> list=new ArrayList<Object>();
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        DocumentBuilder builder=null;
        try{
            builder=factory.newDocumentBuilder();
            Document doc=builder.parse(new ByteArrayInputStream(strXML.getBytes("utf-8")));
            NodeList nodelist=doc.getElementsByTagName(elementName);
            for(int i=0;i<nodelist.getLength();i++){
                Node node=nodelist.item(i);
                NodeList chlist=node.getChildNodes();
                Object bean=Class.forName(className).newInstance();
                Class<?> cls=bean.getClass();
                Method methods[]=cls.getDeclaredMethods();
                Field fields[]=cls.getDeclaredFields();
                for(int j=0;j<chlist.getLength();j++)
                {
                    Node chnode=chlist.item(j);
                    if(chnode instanceof Element)
                    {
                        //System.out.println(chnode.getNodeName()+","+chnode.getTextContent());
                        for(Field field:fields)
                        {
                            String fieldName=field.getName();
                            if(fieldName.equals(chnode.getNodeName())){
                                String fldtype=field.getType().getSimpleName();
                                String setMethod=pareSetName(fieldName);
                                if(!checkMethod(methods,setMethod))
                                {
                                    continue;
                                }
                                Object value=chnode.getTextContent();
                                Method method=cls.getMethod(setMethod,field.getType());
                                if(null != value)
                                {
                                    if("String".equals(fldtype))
                                    {
                                        method.invoke(bean,value.toString());
                                    }
                                    else if("Date".equals(fldtype))
                                    {
                                        Date temp=parseDate(value.toString());
                                        method.invoke(bean,temp);
                                    }
                                    else if("Integer".equals(fldtype) || "int".equals(fldtype))
                                    {
                                        Integer intval=Integer.parseInt(value.toString());
                                        method.invoke(bean,intval);
                                    }
                                    else if("Long".equalsIgnoreCase(fldtype))
                                    {
                                        Long temp=Long.parseLong(value.toString());
                                        method.invoke(bean,temp);
                                    }
                                    else if(fldtype.equalsIgnoreCase("Float"))
                                    {
                                        Float f=Float.parseFloat(value.toString());
                                        method.invoke(bean,f);
                                    }
                                    else if("Double".equalsIgnoreCase(fldtype))
                                    {
                                        Double temp=Double.parseDouble(value.toString());
                                        method.invoke(bean,temp);
                                    }
                                    else if("Boolean".equalsIgnoreCase(fldtype))
                                    {
                                        Boolean temp=Boolean.parseBoolean(value.toString());
                                        method.invoke(bean,temp);
                                    }
                                    else
                                    {
                                        System.out.println("not supper type"+fldtype);
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
                list.add(bean);
            }
        }
        catch(Exception e){
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 拼接某属性set 方法
     * @param fldname
     * @return
     */
    public static String pareSetName(String fldname)
    {
        if(null==fldname || "".equals(fldname))
        {
            return null;
        }
        String pro="set"+fldname.substring(0,1).toUpperCase()+fldname.substring(1);
        return pro;
    }
    /**
     * 判断该方法是否存在
     * @param methods
     * @param met
     * @return
     */
    public static boolean checkMethod(Method methods[],String met)
    {
        if(null != methods)
        {
            for(Method method:methods)
            {
                if(met.equals(method.getName()))
                {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 格式化string为Date
     * @param datestr
     * @return date
     */
    public static Date parseDate(String datestr)
    {
        if(null==datestr || "".equals(datestr))
        {
            return null;
        }
        try
        {
            String fmtstr=null;
            if(datestr.indexOf(':')>0)
            {
                fmtstr="yyyy-MM-dd HH:mm:ss";
            }
            else
            {
                fmtstr="yyyy-MM-dd";
            }
            SimpleDateFormat sdf=new SimpleDateFormat(fmtstr);
            return sdf.parse(datestr);
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
            return null;
        }
    }
    @SuppressWarnings("rawtypes")
    public static void main(String[] args) {
        String strXML="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "<soapenv:Header xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" >" +
                "<ns3:requesthead xmlns:ns3=\"http://pub.webservice.cmp.com\" xmlns:ns2=\"http://pan.prpall.webservice.cmp.com\">" +
                "<ns3:request_type>Q101</ns3:request_type><ns3:uuid>8918211j-12121212</ns3:uuid>" +
                "<ns3:sender>0545</ns3:sender><ns3:server_version>2.0</ns3:server_version>" +
                "<ns3:user>0545</ns3:user><ns3:password>4005973D0841EAC706DC9B8B32858D9D</ns3:password>" +
                "<ns3:areacode>45000000</ns3:areacode><ns3:ChnlNo>yntc</ns3:ChnlNo>" +
                "<ns3:flowintime>2017-05-24 15:00:21</ns3:flowintime></ns3:requesthead>" +
                "</soapenv:Header><soap:Body xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                "<ns2:GETORIGINPOLICYREQ xmlns:ns2=\"http://pan.prpall.webservice.cmp.com\" xmlns:ns3=\"http://pub.webservice.cmp.com\">" +
                "<ns2:BIZ_ENTITY><Policy><LicenseNo>桂QW1231</LicenseNo>" +
                "<LicenseType>02</LicenseType><ComCode>45010200</ComCode>" +
                "<Resource>0524</Resource><InsuredName>寒冰</InsuredName>" +
                "<IdentifyType>01</IdentifyType>" +
                "<IdentifyNumber>220381199203164520</IdentifyNumber>" +
                "<ChannelCode>000002000001</ChannelCode></Policy></ns2:BIZ_ENTITY>" +
                "</ns2:GETORIGINPOLICYREQ></soap:Body></soapenv:Envelope>";
        List list=XmlUtils.parseObject(strXML,"getSupportProvinceResult","java.lang.String");
        for(int i=0;i<list.size();i++){

        }
    }


}
